/* 
 * File:   Grafo.c
 * Author: Vagner Clementino
 *
 * Created on 11 de Março de 2012, 11:24
 */

#include <stdlib.h>
#include <stdio.h>
#include "Grafo.h"

Grafo* cria_grafo(int num_alunos, int num_universidades) {

    pGrafo G = NULL;
    int i;

    G = (Grafo*) malloc(sizeof (Grafo));
    if (G == NULL) {
        fprintf(stderr, "Erro ao alocar memoria para a estrutura Grafo.\n");
        exit(-20);
    }

    G->num_alunos = num_alunos;
    G->num_universidades = num_universidades;

    G->dados = (aresta**) malloc(num_universidades * (sizeof (aresta*)));

    if (G->dados == NULL) {
        fprintf(stderr, "Erro ao alocar memoria para a estrutura Grafo.\n");
        exit(-21);
    }

    for (i = 0; i < num_alunos; i++) {
        G->dados[i] = (aresta*) malloc(num_alunos * sizeof (aresta));

        if (G->dados[i] == NULL) {
            fprintf(stderr, "Erro ao alocar memoria para a estrutura Grafo.\n");
            exit(-22);
        }
    }
    return G;

}

void desaloca_grafo(Grafo* g) {

    int i;
    for (i = 0; i < g->num_alunos; i++) {
        free(g->dados[i]);
    }
    free(g->dados);
    free(g);
}

void inicializa_grafo(Grafo** g) {
    int i, j;
    for (i = 0; i < (*g)->num_alunos; i++) {
        for (j = 0; j < (*g)->num_universidades; j++) {
            (*g)->dados[i][j].tem_aresta = FALSO;
            (*g)->dados[i][j].satisfacao = INFINITO;
            (*g)->dados[i][j].nota_aluno = INFINITO;           
        }
    }
}

void imprime_grafo(const Grafo* g) {
    int i, j;
    for (i = 0; i < g->num_alunos; i++) {
        for (j = 0; j < g->num_universidades; j++) {
            printf("Linha %d coluna %d\n", i, j);
            if (g->dados[i][j].tem_aresta == FALSO) {
                printf("Tem aresta: Falso\n");
            } else {
                printf("Tem aresta: Verdadeiro\n");
            }

            if (g->dados[i][j].satisfacao == INFINITO) {
                printf("Satisfacao: INFINITO\n");
            } else {
                printf("Satisfacao: %d\n", g->dados[i][j].satisfacao);
            }

            if (g->dados[i][j].nota_aluno == INFINITO) {
                printf("Nota aluno: INFINITO\n");
            } else {
                printf("Nota: %d\n", g->dados[i][j].nota_aluno);
            }           
        }
        printf("\n\n");
    }
    printf("\n\n");
}

bool esta_matriculado(int id_aluno, const Grafo* g) {
    int i;
    bool matriculado = FALSO;

    for (i = 0; i < g->num_universidades; i++) {
        if (g->dados[id_aluno][i].tem_aresta == VERDADEIRO) {
            matriculado = VERDADEIRO;
            break;
        }
    }
    return matriculado;
}

int retorna_candidato_troca(int id_universidade, Grafo* g, int heuristica) {
    int i;
    int comparador = INFINITO;
    int id_candidato = INFINITO;

    switch (heuristica) {
        case 1:
            for (i = 0; i < g->num_alunos; i++) {
                if (g->dados[i][id_universidade].tem_aresta == VERDADEIRO) {
                    if (comparador == INFINITO) {
                        comparador = g->dados[i][id_universidade].satisfacao;
                        id_candidato = i;
                    } else {
                        if (g->dados[i][id_universidade].satisfacao < comparador) {
                            id_candidato = i;
                        }
                    }
                }
            }
            break;

        case 2:
            for (i = 0; i < g->num_alunos; i++) {
                if (g->dados[i][id_universidade].tem_aresta == VERDADEIRO) {
                    if (comparador == INFINITO) {
                        comparador = g->dados[i][id_universidade].nota_aluno;
                        id_candidato = i;
                    } else {
                        if (g->dados[i][id_universidade].nota_aluno < comparador) {
                            id_candidato = i;
                        }
                    }
                }
            }
            break;

    }


    return (id_candidato);
}



